package com.cskaoyan.javase.oop3._2inner._3local._2usecase;

import sun.security.x509.AVA;

/**
 * 局部内部类的两个经典使用场景：
 *      1.假如方法需要一个返回值，返回一个对象。
 *          这时普遍的做法是返回一个匿名对象。
 *          但如果我们需要在重写类的基础上，返回这个类的子类对象，怎么办呢？
 *          常规的做法是 定义一个子类，然后创建子类对象
 *          但是学习了局部内部类以后,我们可以在方法中写一个局部内部类来继承外部的一个类,然后创建它的对象,作为返回值.
 *
 *      2.假如方法调用需要传入一个子类对象,那么我们就可以在方法调用的位置写一个局部内部类,然后创建它的对象,作为参数.
 *
 *  以上两种方式,都是十分常见的,局部内部类的典型用途.
 *  局部内部类使用的优点:
 *          1.封装隐藏,该类对外界不可见
 *          2.稍微比手写实现类/子类,简洁一丢丢(但是它有很大的简化空间)
 *
 *  缺点:
 *          1.是一个一次性的类,在方法外部不可见.如果有多次使用实现类/子类的需求,使用局部内部类就是画蛇添足了.
 *
 *
 * @since 15:01
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        A a = method();
        a.test();

        class B extends AbstractB {
            @Override
            public void test() {
                System.out.println("我是局部内部类实现的类B");
            }
        }
        method(new B());
    }

    public static void method(AbstractB ab) {
        ab.test();
    }

    public static A method() {
        // 常规做法
        // return new ASon();
        // 使用局部内部类
        class ASon extends A {
            @Override
            void test() {
                System.out.println("我是局部内部类!");
            }
        }
        return new ASon();
    }
}

class A {
    void test() {
        System.out.println("测试");
    }
}

class ASon extends A {
    @Override
    void test() {
        System.out.println("重写");
    }
}

abstract class AbstractB {
    public abstract void test();
}

class B extends AbstractB {
    @Override
    public void test() {
        System.out.println("我是手写实现的类B");
    }
}